import axios from 'axios'
const MD5 = require('js-md5')

class Haier {
    constructor(options) {
        this._req = axios.create.call(this, options)
        this._req.defaults.withCredentials = true
    }

    request({ url, method, data, query }, params = {}) {
        return new Promise((resolve, reject) => {
            this._req.request(Object.assign(params, {
                url: url,
                method: method,
                data: data,
                params: query
            })).then(({ data }) => {
                let { status } = data
                if (status == 2000) {
                    resolve(data)
                } else {
                    reject(data)
                }
            })
        })
    }

    get(url, query, params) {
        return this.request({
            url: url,
            method: "GET",
            query: query
        }, params)
    }

    post(url, data, params) {
        return this.request({
            url: url,
            method: "POST",
            data: data
        }, params)
    }

    delete(url, query, params) {
        return this.request({
            url: url,
            method: "DELETE",
            query: query
        }, params)
    }

    put(url, data, params) {
        return this.request({
            url: url,
            method: 'PUT',
            data: data
        }, params)
    }
}

const mapping = function (o, mapping, vm) {
    if (!(o instanceof Object)) {
        console.error("mapping object error")
        return
    }
    for (const [k, v] of Object.entries(mapping)) {
        let _value = o[k] ? o[k] : o[v]
        vm.$set(o, k, _value)
        Object.defineProperty(o, k, {
            configurable: true,
            get: () => _value,
            set: (v) => _value = v
        })
    }
}

/* eslint-disable */
const callback = function ({ }, { arg, value, modifiers }, { context }) {
    if (!(arg && context[arg] instanceof Object)) {
        console.error("require configure mapping!")
        return
    }
    var source = value;
    if (modifiers.array || source instanceof Array) {
        source.forEach(item => mapping(item, context[arg], context))
    } else if (source instanceof Object) {
        mapping(source, context[arg], context)
    } else {
        console.error("require configure mapping!")
    }
}

const arg = function (name, args) {
    if (args instanceof Array)
        return `${name}(${args.join(",")})`
    return `${name}()`
}

const args = function (o) {
    let arr = []
    for (const [k, v] of Object.entries(o)) arr.push(arg(k, v))
    return arr.join(":")
}


const minix = {
    methods: {
        requireLogin() {
            return new Promise((resolve, reject) => {
                var status = localStorage.getItem('status')
                status ? resolve() : reject()
            })
        },
        getAssets(name, count = 1) {
            return this.$haier.get('openapi/list/related', {
                assetsName: name,
                count: count
            })
        }
    }
}

export default {
    install(Vue, options) {
        let { baseURL } = options
        Vue.prototype.$haier = new Haier(options)
        /**
         * 数据字段映射指令
         */
        Vue.directive("mapping", {
            bind: callback,
            update: callback
        })
        Vue.prototype.$arg = args

        Vue.mixin(minix)
        Vue.prototype.$url = function (path) {
            return `${baseURL}${path}`
        }
        Vue.prototype.$md5 = MD5

        Vue.prototype.$getImgURI = function(assets){
            var urls = assets.content.split("/")
            if (urls.length == 1) return `${baseURL}openapi/assets/${urls[0]}`
            return `${baseURL}openapi/assets/${urls.slice(urls.length - 1)}?path=commodity/${urls[2]}`
        }
    }
}